import {
	_decorator,
	Component,
	Node,
	systemEvent,
	SystemEvent,
	EventKeyboard,
	KeyCode,
	log,
	v3,
	RigidBody,
	Vec3,
	Collider,
	PhysicsSystem,
	System,
	EventMouse,
	v2,
	game,
	Quat,
	quat,
} from "cc";
const { ccclass, property } = _decorator;

enum State {
	idle,
	jump,
}
const qt: Quat = quat();
const qt2=quat();
@ccclass("CameraPlayer")
export class CameraPlayer extends Component {
	@property(Node)
	eyeNode: Node = null;

	@property
	speed: number = 6;

	@property
	rotateSpeed: number = 3;

	state: State = State.idle;

	_rotation: Vec3 = v3();
	angle: Vec3;
	eye: Vec3;

	inputList: Map<KeyCode, boolean> = new Map();

	onLoad() {
		systemEvent.on(SystemEvent.EventType.KEY_DOWN, this.onKeyDown, this);
		systemEvent.on(SystemEvent.EventType.KEY_UP, this.onKeyUp, this);

		systemEvent.on(SystemEvent.EventType.MOUSE_UP, this.onMouseUp, this);
		systemEvent.on(
			SystemEvent.EventType.MOUSE_DOWN,
			this.onMouseDown,
			this
		);
		systemEvent.on(
			SystemEvent.EventType.MOUSE_MOVE,
			this.onMouseMove,
			this
		);

		let collider = this.getComponent(Collider);
		collider.on("onCollisionEnter", this.onCollisionEnter, this);
	}

	start() {
		Vec3.copy(this._rotation, this.node.eulerAngles);
	}

	update(deltaTime: number) {
		this.cameraMove(deltaTime);
		this.onMove();
		this.onJump();
		this.onRotate();
	}

	onRotate() {
		let rigidBody = this.node.getComponent(RigidBody);
		// let angular = this.node.eulerAngles as Vec3;
		let angular = v3(0, 0, 0);
		if (this.inputList[KeyCode.KEY_Q]) {
			angular.y += this.rotateSpeed;
		}
		if (this.inputList[KeyCode.KEY_E]) {
			angular.y -= this.rotateSpeed;
		}
		rigidBody.setAngularVelocity(angular);
	}

	onJump() {
		if (this.state == State.jump) {
			return;
		}
		let rigidBody = this.node.getComponent(RigidBody);
		if (this.inputList[KeyCode.SPACE]) {
			rigidBody.applyForce(v3(0, 300, 0));
			this.state = State.jump;
		}
	}

	onMove() {
		let v: Vec3 = v3();
		let rigidBody = this.node.getComponent(RigidBody);
		rigidBody.getLinearVelocity(v);
		v = v3(0, v.y, 0);
		if (this.inputList[KeyCode.ARROW_UP] || this.inputList[KeyCode.KEY_W]) {
			v.z = -this.speed;
		}
		if (
			this.inputList[KeyCode.ARROW_DOWN] ||
			this.inputList[KeyCode.KEY_S]
		) {
			v.z = this.speed;
		}
		if (
			this.inputList[KeyCode.ARROW_LEFT] ||
			this.inputList[KeyCode.KEY_A]
		) {
			v.x = -this.speed;
		}
		if (
			this.inputList[KeyCode.ARROW_RIGHT] ||
			this.inputList[KeyCode.KEY_D]
		) {
			v.x = this.speed;
		}

		if (
			this.inputList[KeyCode.ARROW_RIGHT] ||
			this.inputList[KeyCode.KEY_D]
		) {
			v.x = this.speed;
		}
		if(this.inputList[KeyCode.ESCAPE]){
			if (document.exitPointerLock) {
				document.exitPointerLock();
			}
		}
		//根据当前角度进行旋转,使移动可以根据旋转的角度进行
		Vec3.transformQuat(v, v, this.node.getRotation());
		rigidBody?.setLinearVelocity(v);
	}

	onKeyDown(e: EventKeyboard) {
		this.inputList[e.keyCode] = true;
	}

	onKeyUp(e: EventKeyboard) {
		this.inputList[e.keyCode] = false;
	}

	onMouseUp(e: EventMouse) {
		
	}

	onMouseDown(e: EventMouse) {
		if(e.getButton()==0&&game.canvas.requestPointerLock){
			game.canvas.requestPointerLock();
		}
	}

	cameraMove(deltaTime: number) {
		//this.node.eulerAngles=this.angle;
		//this.eyeNode.eulerAngles=this.eye;
		// this.node.setRotation(this.horizontal);

		let euler = v3();
		this.vertical.getEulerAngles(euler);
		if (euler.x > -60 && euler.x < 60) {
			Quat.lerp(qt, this.eyeNode.rotation, this.vertical, deltaTime*10);
			this.eyeNode.setRotation(qt);
		}

		Quat.lerp(qt2, this.node.rotation, this.horizontal, deltaTime*10);
		this.node.setRotation(qt2);
	}

	horizontal = quat();
	vertical = quat();
	onMouseMove(e: EventMouse) {
		let delta = e.getDelta();
		this.angle = this.node.eulerAngles as Vec3;
		this.eye = this.eyeNode.eulerAngles as Vec3;

		this.angle.y -= delta.x * this.rotateSpeed;
		this.eye.x += delta.y * this.rotateSpeed;

		//限制y轴
		if (this.eye.x > 60) {
			this.eye.y = 60;
		}
		if (this.eye.y < -60) {
			this.eye.y = -60;
		}

		this._rotation.y -= delta.x * this.rotateSpeed;
		this._rotation.x += delta.y * this.rotateSpeed;

		this.horizontal = this.node.getRotation();
		this.vertical = this.eyeNode.getRotation();

		Quat.rotateAround(
			this.horizontal,
			this.horizontal,
			Vec3.UNIT_Y,
			-e.getDeltaX() * this.rotateSpeed
		);
		Quat.rotateAround(
			this.vertical,
			this.vertical,
			Vec3.UNIT_X,
			e.getDeltaY() * this.rotateSpeed
		);
	}

	onCollisionEnter() {
		this.state = State.idle;
	}
}
